// Raf Lempens & Bjorn Schobben
#include "QtWorld.h"

#include "QtWall.h"
#include "QtRobot.h"
#include "QtPusher.h"
#include "QtLaser.h"
#include "QtSpinner.h"

QtWorld::QtWorld(): animations(0)
{
}


QtWorld::~QtWorld()
{
}

void QtWorld::BeginBehaviorSimulation()
{
	animationLog.BeginCommandGroup();
}

void QtWorld::EndBehaviorSimulation()
{
	animationLog.EndCommandGroup();
}


void QtWorld::Play()
{
	if (!animationLog.Empty())
	{
		animationLog.Execute();
	}
	else
	{
		emit LogFinished();
	}
}

Board* QtWorld::CreateBoard()
{
	QtBoard* board = new QtBoard();

	board->AddToScene(this);
	board->SetTileManager(&tileManager);

	return board;
}

Wall* QtWorld::CreateWall(const Direction& direction, unsigned int cellX, unsigned int cellY)
{
	QtWall *wall = new QtWall(cellX, cellY);
	wall->SetDirection(direction);

	QtWallSprite* sprite = wall->GetSprite();
	sprite->SetDirection(direction);
	sprite->SetPixmap( tileManager.Tile(*sprite, "foreground") );
	sprite->SetPosition(QPoint(cellX*CELLSIZE, cellY*CELLSIZE));
	sprite->SetCellSize(CELLSIZE, CELLSIZE);
	sprite->AddToScene(this);

	QObject::connect(sprite, SIGNAL(Finished()), this, SLOT(OnAnimationFinished()));
	QObject::connect(sprite, SIGNAL(Started()), this, SLOT(OnAnimationStarted()));

	return wall;	
}

Pusher* QtWorld::CreatePusher(const Direction& direction, unsigned int cellX, unsigned int cellY)
{
	QtPusher *pusher = new QtPusher(cellX, cellY);
	pusher->SetDirection(direction);
	pusher->SetAnimationLog(&animationLog);

	QtPusherSprite* sprite = pusher->GetSprite();
	sprite->SetDirection(direction);
	sprite->SetPixmap( tileManager.Tile(*sprite, "foreground") );
	sprite->SetPosition(QPoint(cellX*CELLSIZE, cellY*CELLSIZE));
	sprite->SetCellSize(CELLSIZE, CELLSIZE);
	sprite->AddToScene(this);

	QObject::connect(sprite, SIGNAL(Finished()), this, SLOT(OnAnimationFinished()));
	QObject::connect(sprite, SIGNAL(Started()), this, SLOT(OnAnimationStarted()));

	return pusher;	
}

Laser* QtWorld::CreateLaser(const Direction& direction, unsigned int cellX, unsigned int cellY)
{
	QtLaser *laser = new QtLaser(cellX, cellY);
	laser->SetDirection(direction);
	laser->SetAnimationLog(&animationLog);

	QtLaserSprite* sprite = laser->GetSprite();
	sprite->SetDirection(direction);
	sprite->SetPixmap( tileManager.Tile(*sprite, "foreground") );
	sprite->SetPosition(QPoint(cellX*CELLSIZE, cellY*CELLSIZE));
	sprite->SetCellSize(CELLSIZE, CELLSIZE);
	sprite->AddToScene(this);

	QObject::connect(sprite, SIGNAL(Finished()), this, SLOT(OnAnimationFinished()));
	QObject::connect(sprite, SIGNAL(Started()), this, SLOT(OnAnimationStarted()));

	return laser;	
}

Robot* QtWorld::CreateRobot(const std::string& type, unsigned int cellX, unsigned int cellY)
{
	QtRobot *robot = new QtRobot(type, cellX, cellY);
	robot->SetAnimationLog(&animationLog);

	QtRobotSprite* sprite = robot->GetSprite();
	sprite->SetPixmap( tileManager.Tile(*sprite, "robot") );
	sprite->SetPosition(QPoint(cellX*CELLSIZE, cellY*CELLSIZE));
	sprite->SetMovementDistance(CELLSIZE);
	sprite->AddToScene(this);

	QObject::connect(sprite, SIGNAL(Finished()), this, SLOT(OnAnimationFinished()));
	QObject::connect(sprite, SIGNAL(Started()), this, SLOT(OnAnimationStarted()));

	return robot;	
}

Spinner* QtWorld::CreateSpinner(const Direction& direction, unsigned int cellX, unsigned int cellY)
{
	QtSpinner *spinner = new QtSpinner(cellX,cellY);
	spinner->SetDirection(direction);
	spinner->SetAnimationLog(&animationLog);

	QtSpinnerSprite* sprite = spinner->GetSprite();
	sprite->SetDirection(direction);
	sprite->SetPixmap( tileManager.Tile(*sprite, "foreground") );
	sprite->SetPosition(QPoint(cellX*CELLSIZE, cellY*CELLSIZE));
	sprite->AddToScene(this);

	QObject::connect(sprite, SIGNAL(Finished()), this, SLOT(OnAnimationFinished()));
	QObject::connect(sprite, SIGNAL(Started()), this, SLOT(OnAnimationStarted()));

	return spinner;
}


void QtWorld::OnAnimationStarted()
{
	animations++;
	printf("animations = %d\n", animations);
}

void QtWorld::OnAnimationFinished()
{
	animations--;

	printf("animations = %d\n", animations);

	if (animations == 0)
	{
		if (!animationLog.Empty())
			animationLog.DropFront();

		Play();
	}
}
